/*
 * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved
 * Use is subject to license terms.
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#if defined(UNIT_TEST)
#include "unit_test.h"
#else

#include "apr.h"
#include "apr_strings.h"
#include "apr_thread_proc.h"
#include "apr_hash.h"
#include "apr_user.h"
#include "apr_lib.h"
#include "apr_optional.h"
#include "apr_xml.h"
#include "apr_uuid.h"

#define APR_WANT_STRFUNC
#define APR_WANT_MEMFUNC
#include "apr_want.h"

#include "ap_config.h"
#include "util_xml.h"
#include "util_filter.h"
#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
#include "http_request.h"
#include "http_core.h"
#include "http_protocol.h"
#include "http_log.h"
#include "http_main.h"
#include "util_script.h"
#include "http_core.h"

#endif

#define ATOM_DIR "atom"
#define COLLECTION_FILE "collection.atom"
#define CSS_DIR "css"
#define ENTRIES_COLL "entries"
#define ENTRIES_DIR "e"
#define ENTRY_CSS "entry.css"
#define ENTRY_JS "entry.js"
#define ENTRY_TEMPLATE "entry"
#define EXTRAS_DIR "x"
#define FEED_FILE "feed.atom"
#define FRONT_PAGE "index.html"
#define FRONT_PAGE_CSS "front.css"
#define FRONT_PAGE_JS "front.js"
#define FRONT_PAGE_TEMPLATE "front"
#define GENERATOR "Brought to you by the awesome power of XML, the Atom Publishing Protocol, the Apache Web server, and mod_atom."
#define HTML_OPTIONS_FILE "html"
#define ID_FILE "id."
#define JS_DIR "js"
#define LINK_PREFIX "L."
#define MEDIA_COLL "media"
#define MEDIA_DIR "m"
#define MEDIA_TYPE_SUFFIX "mt"
#define METAPUB_SUBS "s"
#define OPTIONS_DIR "options"
#define PUB_DIR "pub"
#define SERVICE_FILE "pub.atomsvc"
#define TEMP_PREFIX "T."
#define TEMPLATES_DIR "templates"

#define WEAK_PREFIX "W/"

#define PERMS APR_FPROT_UREAD|APR_FPROT_UWRITE|APR_FPROT_UEXECUTE|APR_FPROT_GREAD|APR_FPROT_GWRITE|APR_FPROT_GEXECUTE

#define MAX_FILENAME_VARIATIONS 2

#define DEFAULT_ENTRIES_IN_FEED 20

#define ATOM_NS "http://www.w3.org/2005/Atom"
#define APP_NS "http://www.w3.org/2007/app"
#define XHTML_NS "http://www.w3.org/1999/xhtml"
#define XML_NS "http://www.w3.org/XML/1998/namespace"
#define MOD_ATOM_NS "http://www.mod-atom.net/ns"

/* predefined elements */
#define APP_ACCEPT_E 0
#define APP_CATEGORIES_E (APP_ACCEPT_E + 1)
#define APP_COLLECTION_E (APP_CATEGORIES_E + 1)
#define APP_EDITED_E (APP_COLLECTION_E + 1)
#define APP_SERVICE_E (APP_EDITED_E + 1)
#define APP_WORKSPACE_E (APP_SERVICE_E + 1)

#define ATOM_AUTHOR_E (APP_WORKSPACE_E + 1)
#define ATOM_CATEGORY_E (ATOM_AUTHOR_E + 1)
#define ATOM_CONTENT_E (ATOM_CATEGORY_E + 1)
#define ATOM_CONTRIBUTOR_E (ATOM_CONTENT_E + 1)
#define ATOM_EMAIL_E (ATOM_CONTRIBUTOR_E + 1)
#define ATOM_ENTRY_E (ATOM_EMAIL_E + 1)
#define ATOM_FEED_E (ATOM_ENTRY_E + 1)
#define ATOM_GENERATOR_E (ATOM_FEED_E + 1)
#define ATOM_ICON_E (ATOM_GENERATOR_E + 1)
#define ATOM_ID_E (ATOM_ICON_E + 1)
#define ATOM_LINK_E (ATOM_ID_E + 1)
#define ATOM_LOGO_E (ATOM_LINK_E + 1)
#define ATOM_NAME_E (ATOM_LOGO_E + 1)
#define ATOM_PUBLISHED_E (ATOM_NAME_E + 1)
#define ATOM_RIGHTS_E (ATOM_PUBLISHED_E + 1)
#define ATOM_SOURCE_E (ATOM_RIGHTS_E + 1)
#define ATOM_SUBTITLE_E (ATOM_SOURCE_E + 1)
#define ATOM_SUMMARY_E (ATOM_SUBTITLE_E + 1)
#define ATOM_TITLE_E (ATOM_SUMMARY_E + 1)
#define ATOM_UPDATED_E (ATOM_TITLE_E + 1)
#define ATOM_URI_E (ATOM_UPDATED_E + 1)

#define ATOM_ELEMENT_MAX (ATOM_URI_E + 1)

/* predefined attributes */
#define META_A 0
#define FIXED_A (META_A + 1)
#define HREFLANG_A (FIXED_A + 1)
#define HREF_A (HREFLANG_A + 1)
#define LABEL_A (HREF_A + 1)
#define LENGTH_A (LABEL_A + 1)
#define REL_A (LENGTH_A + 1)
#define SCHEME_A (REL_A + 1)
#define SRC_A (SCHEME_A + 1)
#define TERM_A (SRC_A + 1)
#define TITLE_A (TERM_A + 1)
#define TYPE_A (TITLE_A + 1)
#define URI_A (TYPE_A + 1)
#define VERSION_A (URI_A + 1)

/* predefined namespaces */
#define NO_NS 0
#define ATOM_NS_NUM (NO_NS + 1)
#define APP_NS_NUM (ATOM_NS_NUM + 1)
#define XHTML_NS_NUM (APP_NS_NUM + 1)
#define MOD_ATOM_NS_NUM (XHTML_NS_NUM + 1)
#define NS_NUM_MAX (MOD_ATOM_NS_NUM + 1)

#define ATOM_ATTRIBUTE_MAX (VERSION_A + 1)

#include "genx.h"

/* simplified regex */
#define MATCHER(regex, string) ap_regexec(regex, string, 0, NULL, 0)

/* oh dear, globals polluting httpd's namespace :( */
char * atom_join(apr_pool_t * pool, ...);

genxStatus atom_genx_start_elem(void * w_p, int e_num);
genxStatus atom_genx_add_attr(void * w_p, int a_num, char * value);
genxStatus atom_genx_add_ns(void * w_p, int ns_num);
genxStatus atom_genx_end_elem(void * w_p);
genxSender * atom_genx_sender(void * w_p);
genxStatus atom_genx_send(void * w_p, char * data);
genxStatus atom_genx_end_doc(void * w_p);
genxWriter atom_genx_get_writer(void * w_p);
genxStatus atom_genx_nl(void * w_p);

genxStatus atom_genx_simple_elem(void * w_p, int e_num, char * content);
void * atom_genx_client_writer(apr_pool_t * p, request_rec * r,
			       char * * problem_p);
void * atom_genx_file_writer(apr_pool_t * p, apr_file_t * f,
			     char * * problem_p);
genxStatus atom_genx_add_char(void * w_p, int c);

void atom_iter_init(apr_pool_t * pool);
char * atom_iter_new(apr_pool_t * pool, char * dir, void * * iter_p);
char * atom_iter_next(void * iter, char * * next_p);

void atom_filter_init(apr_pool_t * pool);
char * atom_filter_text_construct(apr_pool_t * pool, apr_xml_doc * doc,
				  apr_xml_elem * e, genxWriter w, int html);

char * atom_snarf(char * filename, char * *  ret, apr_pool_t * pool);
int atom_file_exists(char * name, apr_pool_t * pool);

void atom_write_cdata(apr_text * text, genxWriter gw);

/* a little misleading since MEDIA_TYPE only appears on atom:content
 *  which isn't strictly speaking a text construct.
 */
typedef enum {
    XHTML_TYPE, HTML_TYPE, TEXT_TYPE, MEDIA_TYPE
} text_construct_type_t;

/* The types of files that appear in our directory tree
 */
typedef enum {
    ATOM_ENTRY, LINK_FILE, OTHER_FILE
} file_type_t;

    text_construct_type_t atom_text_construct_type(apr_xml_elem * e);

